﻿using System;
using System.Collections.Generic;
using System.Data;
using viBlog.Classes;
using viBlog.Providers;
using visinia.SmartEngine.Cache;

namespace viBlog.Controllers
{
    /// <summary>
    /// The blog data filter controller
    /// used to filter data like by posts, by category, by tag
    /// </summary>
    public class DataFilterController
    {
        public enum FILTER
        {
            LATEST_BY_DATE = 1,
            LATEST_BY_CATEGORY = 2,
            LATEST_BY_TAG = 3,
            POSTS_LIST = 4,
        }

        #region ACCESS
        /// <summary>
        /// Gets all the filters
        /// </summary>
        /// <returns>List of all filters</returns>
        public static List<viBlogDataFilter> GetFilters()
        {
            List<viBlogDataFilter> list = (List<viBlogDataFilter>)DataCache.GetCache("postFiltersAll");
            if (list == null)
            {
                list = FillFilters(viBlogDataProvider.Provider.GetFilters());
                DataCache.SetCache("postFiltersAll", list);
            }
            return list;
        }

        /// <summary>
        /// Gets the specified filter
        /// </summary>
        /// <param name="ModuleId">The module id whose filter to return</param>        
        public static viBlogDataFilter GetFilter(int ModuleId)
        {
            return GetFilters().Find(p => p.ModuleId == ModuleId);             
        }
        #endregion

        #region DATA
        /// <summary>
        /// Adds a new data filter
        /// </summary>
        /// <param name="filter"></param>
        public static void AddFilter(viBlogDataFilter filter)
        {
            viBlogDataProvider.Provider.AddFilter(Convert.ToInt32(filter.FilterType), filter.ModuleId, filter.Data, filter.ItemsCount);
            DataCache.DeleteCacheMultiple("postFilter");
        }

        /// <summary>
        /// Updates the data filter
        /// </summary>
        /// <param name="filter"></param>
        public static void UpdateFilter(viBlogDataFilter filter)
        {
            viBlogDataProvider.Provider.UpdateFilter(filter.FilterId, Convert.ToInt32(filter.FilterType), filter.ModuleId, filter.Data, filter.ItemsCount);
            DataCache.DeleteCacheMultiple("postFilter");
        }

        /// <summary>
        /// Deletes the specified filter
        /// </summary>
        /// <param name="FilterId"></param>
        public static void DeleteFilter(int FilterId)
        {
            viBlogDataProvider.Provider.DeleteFilter(FilterId);
            DataCache.DeleteCacheMultiple("postFilter");
        }
        #endregion

        #region HELPERS        
        private static List<viBlogDataFilter> FillFilters(IDataReader dr)
        {
            List<viBlogDataFilter> list = new List<viBlogDataFilter>();
            while (dr.Read())
            {
                list.Add(ActualRead(dr));
            }
            dr.Close();
            return list;
        }
        private static viBlogDataFilter ActualRead(IDataReader dr)
        {
            viBlogDataFilter filter = new viBlogDataFilter();
            if (dr["FilterId"] != Convert.DBNull)
                filter.FilterId = (int)dr["FilterId"];
            if (dr["FilterType"] != Convert.DBNull)
                filter.FilterType = (FILTER)dr["FilterType"];
            if (dr["ModuleId"] != Convert.DBNull)
                filter.ModuleId = (int)dr["ModuleId"];
            if (dr["Data"] != Convert.DBNull)
                filter.Data = (string)dr["Data"];
            if (dr["ItemsCount"] != Convert.DBNull)
                filter.ItemsCount = (int)dr["ItemsCount"];
            return filter;
        }
        #endregion

        #region DATA ACCESS HELPERS

        private const string KEY_FILTERED_POSTS = "postFilterData_{0}";
        private const int FILTERED_POSTS_EXPIRY = 20;

        /// <summary>
        /// The actual filter controller method
        /// </summary>
        /// <param name="ModuleId"></param>
        /// <returns></returns>
        public static List<Post> GetFilteredData(int ModuleId)
        {
            viBlogDataFilter filter = GetFilter(ModuleId);
            if (filter == null)
                return null;
            if (filter.ItemsCount == 0)
                return null;
            string key = string.Format(KEY_FILTERED_POSTS, filter.FilterId);
            //List<Post> list = (List<Post>)DataCache.GetCache(key);
            ///if (list != null)
            //    return list;
            //else
            List<Post> list = new List<Post>();
            {
                int temp = 0;
                switch (GetFilter(ModuleId).FilterType)
                {
                    case FILTER.LATEST_BY_DATE:
                        list = PostController.GetPosts(filter.ItemsCount);
                        //DataCache.SetCache(key, list, new TimeSpan(0, FILTERED_POSTS_EXPIRY, 0));
                        return list;
                    case FILTER.LATEST_BY_CATEGORY:
                        if (Int32.TryParse(filter.Data, out temp))
                        {
                            Category category = CategoryController.GetCategory(temp);
                            if (category == null)//category does'nt exist
                                return null;
                            list = PostController.GetPosts(category, filter.ItemsCount);
                            //DataCache.SetCache(key, list, new TimeSpan(0, FILTERED_POSTS_EXPIRY, 0));
                            return list;
                        }
                        return null;
                    case FILTER.LATEST_BY_TAG:
                        if (Int32.TryParse(filter.Data, out temp))
                        {
                            Tag tag = TagController.GetTags().Find(p => p.TagId == temp);
                            if (tag == null)// tag does'nt exist
                                return null;
                            list = PostController.GetPosts(tag, filter.ItemsCount);
                            //DataCache.SetCache(key, list, new TimeSpan(0, FILTERED_POSTS_EXPIRY, 0));
                            return list;
                        }
                        return null;
                    case FILTER.POSTS_LIST:
                        if (string.IsNullOrEmpty(filter.Data))
                            return null;
                        list = PostController.GetPosts(filter.Data, filter.ItemsCount);
                        //DataCache.SetCache(key, list, new TimeSpan(0, FILTERED_POSTS_EXPIRY, 0));
                        return list;
                }
            }
            return null;
        }

        //public static int GetFilteredDataPagesCount(int ModuleId)
        //{
        //    viBlogDataFilter filter = GetFilter(ModuleId);
        //    if (filter == null)
        //        return 0;
        //    if (filter.ItemsCount == 0)
        //        return 0;
        //    int total = 0;
        //    int count = 0;
        //    {
        //        int temp = 0;
        //        switch (GetFilter(ModuleId).FilterType)
        //        {
        //            case FILTER.LATEST_BY_DATE:
        //                total = PostController.GetPostsCount();                                                
        //                count = total / filter.ItemsCount;
        //                if ((total % filter.ItemsCount) > 0)
        //                    ++count;
        //                return --count;//to make count as zero based
        //            case FILTER.LATEST_BY_CATEGORY:
        //                if (Int32.TryParse(filter.Data, out temp))
        //                {
        //                    Category category = CategoryController.GetCategory(temp);
        //                    if (category == null)//category does'nt exist
        //                        return 0;
        //                    total = PostController.GetPostsCount(category);                                                        
        //                    count = total / filter.ItemsCount;
        //                    if ((total % filter.ItemsCount) > 0)
        //                        ++count;
        //                    return --count;//to make count as zero based
        //                }
        //                return 0;
        //            case FILTER.LATEST_BY_TAG:
        //                if (Int32.TryParse(filter.Data, out temp))
        //                {
        //                    Tag tag = TagController.GetTags().Find(p => p.TagId == temp);
        //                    if (tag == null)// tag does'nt exist
        //                        return 0;
        //                    total = PostController.GetPostsCount(tag);                            
        //                    count = total / filter.ItemsCount;
        //                    if ((total % filter.ItemsCount) > 0)
        //                        ++count;
        //                    return --count;//to make count as zero based
        //                }
        //                return 0;
        //            case FILTER.POSTS_LIST:
        //                if (string.IsNullOrEmpty(filter.Data))
        //                    return 0;
        //                total = PostController.GetPostsCount(filter.Data);                        
        //                count = total / filter.ItemsCount;
        //                if ((total % filter.ItemsCount) > 0)
        //                    ++count;
        //                return --count;//to make count as zero based
        //        }
        //    }
        //    return 0;
        //}

        //public static List<Post> GetFilteredData(int ModuleId, int PageNo)
        //{
        //    viBlogDataFilter filter = GetFilter(ModuleId);
        //    if (filter == null)
        //        return null;
        //    if (filter.ItemsCount == 0)
        //        return null;
        //    List<Post> list = new List<Post>();
        //    int temp = 0;
        //    int AccessCount = 0;
        //    switch (GetFilter(ModuleId).FilterType)
        //    {
        //        case FILTER.LATEST_BY_DATE:
        //            if (GetFilteredDataPagesCount(ModuleId) > PageNo)
        //            {
        //                AccessCount = (filter.ItemsCount * PageNo) + filter.ItemsCount;                        
        //                list = PostController.GetPosts(AccessCount);
        //                if (list.Count < filter.ItemsCount)
        //                    return list.GetRange(filter.ItemsCount * PageNo, list.Count);
        //                return list.GetRange(filter.ItemsCount * PageNo, filter.ItemsCount);
        //            }
        //            return null;
        //        case FILTER.LATEST_BY_CATEGORY:
        //            if (Int32.TryParse(filter.Data, out temp))
        //            {
        //                Category category = CategoryController.GetCategory(temp);
        //                if (category == null)//category does'nt exist
        //                    return null;
        //                AccessCount = (filter.ItemsCount * PageNo) + filter.ItemsCount;                        
        //                list = PostController.GetPosts(category, AccessCount);
        //                if (list.Count < filter.ItemsCount)
        //                    return list.GetRange(filter.ItemsCount * PageNo, list.Count);
        //                return list.GetRange(filter.ItemsCount * PageNo, filter.ItemsCount);
        //            }
        //            return null;
        //        case FILTER.LATEST_BY_TAG:
        //            if (Int32.TryParse(filter.Data, out temp))
        //            {
        //                Tag tag = TagController.GetTags().Find(p => p.TagId == temp);
        //                if (tag == null)// tag does'nt exist
        //                    return null;
        //                AccessCount = (filter.ItemsCount * PageNo) + filter.ItemsCount;                        
        //                list = PostController.GetPosts(tag, AccessCount);
        //                if (list.Count < filter.ItemsCount)
        //                    return list.GetRange(filter.ItemsCount * PageNo, list.Count);
        //                return list.GetRange(filter.ItemsCount * PageNo, filter.ItemsCount);
        //            }
        //            return null;
        //        case FILTER.POSTS_LIST:
        //            if (string.IsNullOrEmpty(filter.Data))
        //                return null;
        //            AccessCount = (filter.ItemsCount * PageNo) + filter.ItemsCount;                    
        //            list = PostController.GetPosts(filter.Data, AccessCount);
        //            if (list.Count < filter.ItemsCount)
        //                return list.GetRange(filter.ItemsCount * PageNo, list.Count);
        //            return list.GetRange(filter.ItemsCount * PageNo, filter.ItemsCount);
        //    }
        //    return null;
        //}
        #endregion
    }
}
